import json

from ninja import Router
from django.core.cache import cache

from apps.agent_applets.user.schema import WaterCardRecordSerializer
from apps.commom.user import WxAppletsLoginSchema, UserSerializer
from apps.schemas import R
from models.choices import TransactionStatus
from models.models import User, AgentOrderInfo, OrderInfo, WaterCardRecord
from utils.auth import AgentAuthBearer
from utils.decorators import handle_exception
from utils.encryption import make_token
from utils.snowflake import generate_random_code
from utils.wx import get_access_token
from water_applets import settings
import requests

agent_user_router = Router(tags=['代理用户'])


@agent_user_router.post("/user/login", summary="微信登录")
@handle_exception("登录失败")
def wx_login(request, data: WxAppletsLoginSchema):
    """
    微信小程序登录
    """
    if not data.code:
        return R.fail(msg="code is required")
    url = settings.WX_LOGIN_URL.format(code=data.code)
    res = requests.get(url)
    if res.status_code != 200:
        return R.fail(msg="code is required")
    res_dict = json.loads(res.content)
    token = get_access_token(settings.AGENT_GET_TOKEN_URL)
    url = settings.WX_GET_PHONE_NUMBER_URL.format(access_token=token)
    headers = {"Content-Type": "application/json"}
    para = {'code': data.phoneCode}
    response = requests.post(url, json=para, headers=headers)
    res = response.json()
    phone_number = ""
    if res['errcode'] == 0:  # 成功获取phonenumber
        phone_number = res['phone_info']['phoneNumber']
    else:
        R.ok(msg="获取手机号失败")
    user, new = User.objects.get_or_create(openid=res_dict['openid'])
    if new:
        # 避免用户邀请码重复
        invite_codes = User.objects.all().values_list('invite_code', flat=True)
        while True:
            invite_code = generate_random_code(10)
            if invite_code not in invite_codes:
                break
        user.invite_code = invite_code
        user.phone_number = phone_number
        # if data.invite_code:
        #     # 邀请码不为空，更新用户邀请人id
        #     invite_user = User.objects.get(invite_code=data.invite_code)
        #     user.invite_id = invite_user.id
        #     InvitationRecord.objects.create(invitee=user, inviter=invite_user, time=timezone.now())
        user.save()
    else:
        user.phone_number = phone_number if user.phone_number != phone_number else user.phone_number
        user.save()
    request.user = user
    token = make_token()
    login_user_key = settings.REDIS_AGENT_APPLETS_LOGIN_TOKEN_KEY.format(user_id=user.id)
    cache.set(login_user_key, token, settings.APPLETS_LOGIN_TOKEN_EXPIRE)
    return R.ok(data={"user": UserSerializer(user).data, "token": token})


@agent_user_router.get("/user/info/{user_id}", summary="获取用户信息", auth=AgentAuthBearer())
@handle_exception("获取用户信息失败")
def get_user(request, user_id: int):
    """
    获取用户信息
    """
    user = User.objects.get(id=user_id)
    return R.ok(data=UserSerializer(user).data)


@agent_user_router.get("/user/income/total", summary="获取用户收益", auth=AgentAuthBearer())
@handle_exception("获取用户收益失败")
def get_income(request):
    """
    获取用户收益
    """
    if request.user.agent_type is None or '普通代理商' in request.user.agent_type.name:
        return R.ok(data=0)
    else:
        if '区域代理商' in request.user.agent_type.name:
            order = AgentOrderInfo.objects.filter(exec_user=request.user, package_id=2).first()
            orders = OrderInfo.objects.filter(address__province_name=order.province,
                                              address__city_name=order.city,
                                              address__district_name=order.district,
                                              transaction_status=TransactionStatus.COMPLETED_PAYMENT)
            income_total = 0
            for item in orders:
                income_total += item.good_number * item.good_spec.regional_agent_price
            return R.ok(data=income_total)
        if '省级代理商' in request.user.agent_type.name:
            order = AgentOrderInfo.objects.filter(exec_user=request.user, package_id=3).first()
            orders = OrderInfo.objects.filter(address__province_name=order.province,
                                              transaction_status=TransactionStatus.COMPLETED_PAYMENT)
            income_total = 0
            for item in orders:
                income_total += item.good_number * item.good_spec.provincial_agent_price
            return R.ok(data=income_total)


@agent_user_router.get("/user/income/list", summary="获取收益列表", auth=AgentAuthBearer())
@handle_exception("获取收益列表失败")
def get_incomes(request):
    orders = None
    if request.user.agent_type is None or '普通代理商' in request.user.agent_type.name:
        return R.ok(data=None)
    if '区域代理商' in request.user.agent_type.name:
        order = AgentOrderInfo.objects.filter(exec_user=request.user, package_id=2).first()
        orders = OrderInfo.objects.filter(address__province_name=order.province,
                                          address__city_name=order.city,
                                          address__district_name=order.district,
                                          transaction_status=TransactionStatus.COMPLETED_PAYMENT)
        result = []
        for index, item in enumerate(orders):
            temp = {
                'id': index,
                "phone_number": item.address.phone_number,
                'income': item.good_spec.regional_agent_price * item.good_number,
                'region': item.address.province_name + item.address.city_name + item.address.district_name,
                'time': item.transaction_time
            }
            result.append(temp)
        return R.ok(data=result)
    if '省级代理商' in request.user.agent_type.name:
        order = AgentOrderInfo.objects.filter(exec_user=request.user, package_id=3).first()
        orders = OrderInfo.objects.filter(address__province_name=order.province,
                                          transaction_status=TransactionStatus.COMPLETED_PAYMENT)
        result = []
        for index, item in enumerate(orders):
            temp = {
                'id': index,
                "phone_number": item.address.phone_number,
                'income': item.good_spec.regional_agent_price * item.good_number,
                'region': item.address.province_name + item.address.city_name + item.address.district_name,
                'time': item.transaction_time
            }
            result.append(temp)
        return R.ok(data=result)


@agent_user_router.get("/user/water_card/list", summary="获取水卡列表", auth=AgentAuthBearer())
@handle_exception("获取水卡列表失败")
def get_water_card(request):
    return R.ok(data=WaterCardRecordSerializer(WaterCardRecord.objects.filter(user=request.user), many=True).data)